/*************************************************************************
> File Name: audio_queue.h
> Author: xueyu-jia
> Mail: 2657575910@qq.com
> Created Time: Mon 08 Apr 2024 10:09:16 AM PDT
 ************************************************************************/
/*
 *该文件用于声明音频，视频和运动的缓存队列
 */
#include<stdatomic.h>
#include<pthread.h>
#include<stdlib.h>
/*
 * 对于音频，视频和运动输出请使用下面的类型而不要使用原生类型
 */
#define Audio_elem  int
#define Vidio_elem  int 
#define Motion_elem int 
//note:明天把整个操作都打包，以后直接调用push和pop，让别人感受不到锁和队列的存在，直接搞成全局的
//note:加入优先级分级机制
/* 下面的代码分别声明了音频(Audio)，视频(Vidio)和运动(Motion)缓存队列的
 * 类型,初始化和释放以及push和pop操作
 * eg:针对音频(Audio)
 * 队列类型:Audio_queue
 * 队列初始化操作:int Audio_queue_alloc(Audio_queue& Audio_queue_ptr,unsigned int size);
 * 队列销毁释放内存操作:void Audio_queue_free(Audio_queue& Audio_queue_ptr)
 * 队列入队操作:bool Audio_queue_push(Audio_queue& Audio_queue_ptr,src,)
 * 队列出队操作:Audio_queue_pop
 */


/*
 * __fifo用于实现多生产者单消费者模型
 */
struct __fifo{
	unsigned int	in;
	pthread_spinlock_t spinlock;//用于保护入队操作
	unsigned int	out;
	unsigned int	mask;
	unsigned int	esize;//每个元素的大小
	void		*data;
};


int __fifo_alloc(struct __fifo *fifo, unsigned int size,size_t esize);
void __fifo_free(struct __fifo *fifo);
bool __fifo_in(struct __fifo *fifo, const void *src);
bool __fifo_out(struct __fifo *fifo, void *dst);

#define DECLARE_QUEUE_TYPE(type) \
	#define ##type_queue __fifo

#define DECLARE_QUEUE_ALLOC(type) \
	#define ##type_queue_alloc(##type_queue_ptr,##type_queue_size) \
		__fifo_alloc(##type_queue_ptr,##type_queue_size,sizeof(##type_elem))

#define DECLARE_QUEUE_FREE(type) \
	#define ##type_queue_free(##type_queue_ptr) \
		__fifo_free(##type_queue_ptr)

#define DECLARE_QUEUE_PUSH(type) \
	#define ##type_queue_push(##type_queue_ptr,src_ptr) \
		__fifo_push(##type_queue_ptr,(void*)src_ptr)

#define DECLARE_QUEUE_POP(type) \
	#define ##type_queue_pop(##type_queue_ptr,dst_ptr) \
		__fifo_pop(##type_queue_ptr,(void*)dst_ptr)

DECLARE_QUEUE_TYPE(Audio);
DECLARE_QUEUE_TYPE(Vidio);
DECLARE_QUEUE_TYPE(Motion);

DECLARE_QUEUE_ALLOC(Audio);
DECLARE_QUEUE_ALLOC(Vidio);
DECLARE_QUEUE_ALLOC(Motion);

DECLARE_QUEUE_FREE(Audio);
DECLARE_QUEUE_FREE(Vidio);
DECLARE_QUEUE_FREE(Motion);

DECLARE_QUEUE_PUSH(Audio);
DECLARE_QUEUE_PUSH(Vidio);
DECLARE_QUEUE_PUSH(Motion);

DECLARE_QUEUE_POP(Audio);
DECLARE_QUEUE_POP(Vidio);
DECLARE_QUEUE_POP(Motion);



